package com.ssfeng.youxia.exceptions;

import com.ssfeng.youxia.bean.JacksonObjectMapper;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import utils.WebUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class YouXiaHandlerExceptionResolver implements HandlerExceptionResolver {

	private static final Logger LOGGER = LoggerFactory.getLogger(YouXiaHandlerExceptionResolver.class);

	@Autowired
	private JacksonObjectMapper jacksonObjectMapper;

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception e) {
		String basePath = (String) request.getAttribute("basePath");
		// log记录异常
		LOGGER.error(e.getMessage(), e);
		// 非控制器请求造成的异常
		if (!(handler instanceof HandlerMethod)) {
			return new ModelAndView("forward:error/500.html");
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler;

		if (WebUtils.isAjaxRequest(request)) {
			Map<String, String> resultMap=new HashMap<>();
			resultMap.put("msg", e.getMessage());
			if (e instanceof UnauthorizedException) {
				resultMap.put("msg", "无权限操作");
			}
			resultMap.put("code", "-1");
			MappingJackson2JsonView view = new MappingJackson2JsonView();
			view.setObjectMapper(jacksonObjectMapper);
			view.setContentType("text/html;charset=UTF-8");
			return new ModelAndView(view, resultMap);
		}

		// 页面指定状态为500，便于上层的resion或者nginx的500页面跳转，由于error/500不适合对用户展示
	    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
		ModelAndView modelAndView=new ModelAndView("forward:error/500.html");
		if (e instanceof UnauthorizedException) {
			modelAndView.setViewName(/*basePath+*/"forward:error/unauthorized.html");
		}
		modelAndView.addObject("error", e.getMessage());
		StringWriter sw=new StringWriter();
		PrintWriter pw=new PrintWriter(sw);
		e.printStackTrace(pw);
		String stacktrace=sw.toString();
		stacktrace = stacktrace.replace(System.getProperty("line.separator"), "<br/>\n");
		modelAndView.addObject("stacktrace", stacktrace);
		return modelAndView;
	}

	public JacksonObjectMapper getJacksonObjectMapper() {
		return jacksonObjectMapper;
	}

	public void setJacksonObjectMapper(JacksonObjectMapper jacksonObjectMapper) {
		this.jacksonObjectMapper = jacksonObjectMapper;
	}

}
